package stack_queue.p2_queue.cyclequeue;

public class CycleQueue {
    private int[] data;
    private int front;
    private int rear;
    private int DEFAULT_CAPACITY = 11;
    public CycleQueue(int capacity) {
        DEFAULT_CAPACITY = capacity;
        data = new int[DEFAULT_CAPACITY];
    }

    public CycleQueue() {
    }

    public void enqueue(int val) {
        if (isEmpty() && data == null) {
            front = rear = 0;
            data = new int[DEFAULT_CAPACITY];
        }
        if (isFull()) {
            throw new RuntimeException("队列已满");
        } else {
            data[rear] = val;
            rear = (rear + 1) % DEFAULT_CAPACITY;
        }
    }

    public void dequeue() {
        if (isEmpty()) {
            throw new RuntimeException("队列已空");
        } else {
            front = (front + 1) % DEFAULT_CAPACITY;
        }
    }

    public int peek() {
        return data[front];
    }

    public boolean isEmpty() {
        return front == rear;
    }

    public boolean isFull() {
        return (rear + 1) % DEFAULT_CAPACITY == front;
    }

    public int getSize() {
        return (rear - front + DEFAULT_CAPACITY) % DEFAULT_CAPACITY;
    }

    public int getCapacity() {
        return DEFAULT_CAPACITY;
    }

    public void clear() {
        front = rear = 0;
        for (int i = 0; i < DEFAULT_CAPACITY; ++i) {
            data[i] = 0;
        }
    }

    public String toString() {
        if (isEmpty()) {
            return "[EMPTY]";
        }
        StringBuilder sb = new StringBuilder();
        sb.append("[FRONT <<");
        for (int i = 0, index = front; i < getSize(); i++) {
            sb.append(String.format(i == rear - 1 ? "%d" : "%d << ", data[index]));
            index = (index + 1) % DEFAULT_CAPACITY;
        }
        return sb.append(" << REAR]").toString();
    }
}
